package com.alibaba.citrus.ots.sales.plan.facade.service.setting;

import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.sales.plan.api.setting.SalesPlanScItemQueryService;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.BatchQuerySalesPlanScItemRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.OrganizationSelectRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.SalesPlanScItemPageQueryRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.SalesPlanScItemQueryRequest;
import com.alibaba.citrus.ots.sales.plan.facade.service.SalesPlanOutCommonService;
import com.alibaba.citrus.ots.sales.plan.repository.PlatformEnhanceRepository;
import com.alibaba.citrus.ots.sales.plan.repository.SalesPlanScItemRepository;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanScItemSDO;
import com.alibaba.cz.base.tool.StringUtil;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.model.dto.BaselineGetOrganizationByIds2Request;
import com.epoch.app.bcots.model.dto.BaselineGetOrganizationByIds2Response;
import com.epoch.app.bcots.model.dto.BaselineGetOrganizationByIdsRequest;
import com.epoch.app.bcots.model.dto.BaselineGetOrganizationByTypeRequest;
import com.epoch.app.bcots.model.dto.OrganizationSDO;
import com.epoch.app.bcots.model.dto.ScItemSDO;
import com.epoch.app.bcots.service.BaseDataService;
import com.epoch.app.otsplatformenhance.api.organizationquery.dto.GetOrganizationByTypeRequest;
import com.epoch.app.otsplatformenhance.api.organizationquery.dto.GetOrganizationByTypeResponse;
import com.epoch.app.otsplatformenhance.api.organizationquery.service.OrganizationQueryService;
import com.epoch.app.otsplatformenhance.enums.OrganizationTypeEnum;
import com.epoch.app.otsplatformenhance.model.dto.GetTopOrganizationListRequest;
import com.epoch.app.otsplatformenhance.model.dto.TopOrganizationListResponse;
import com.epoch.app.otsplatformenhance.sdo.EmployeeSDO;
import com.epoch.app.otsplatformenhance.service.OtsPlatformEnhanceService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author wangyibing
 */
@Service
public class SalesPlanScItemQueryServiceImpl implements SalesPlanScItemQueryService {

    @Resource
    private SalesPlanScItemRepository salesPlanScItemRepository;

    @Resource
    private PlatformEnhanceRepository platformEnhanceRepository;

    @Resource
    private SalesPlanOutCommonService salesPlanOutCommonService;

    @Resource
    private OtsPlatformEnhanceService otsPlatformEnhanceService;

    @Resource
    private BaseDataService baseDataService;

    @Resource
    OrganizationQueryService  organizationQueryService;

    @FacadeInvoker
    @Override
    public Result<PageResult<List<SalesPlanScItemSDO>>> pageQueryProductPlanList(SalesPlanScItemPageQueryRequest planPageQueryRequest) {
        planPageQueryRequestConverter(planPageQueryRequest);
        PageResult<List<SalesPlanScItemSDO>> listPageResult = salesPlanScItemRepository.pageQuerySalesPlanScItemList(planPageQueryRequest);
        if (!Boolean.TRUE.equals(planPageQueryRequest.getIsOutInvoker())) {
            listPageResultConverter(listPageResult);
        }
        return Result.success(listPageResult);
    }

    private void planPageQueryRequestConverter(SalesPlanScItemPageQueryRequest planPageQueryRequest) {
        if (planPageQueryRequest.getBizType() != null) {
            if (StringUtil.isBlank(planPageQueryRequest.getOrgBusinessUnitCode())) {
               //查询自己所属的业务单元
                OrganizationSelectRequest organizationSelectRequest = new OrganizationSelectRequest();
                organizationSelectRequest.setRelatedOrganizationType(planPageQueryRequest.getRelatedOrganizationType());
                organizationSelectRequest.setRelatedOrganizationId(planPageQueryRequest.getRelatedOrganizationId());
                List<OrganizationSDO> organizationSDOList = organizationSDOList(organizationSelectRequest);
                if (CollectionUtils.isNotEmpty(organizationSDOList)) {
                    List<String> orgBusinessUnitCodes = organizationSDOList.stream().map(OrganizationSDO::getId).distinct().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
                    planPageQueryRequest.setOrgBusinessUnitCodes(orgBusinessUnitCodes);
                }
            }
        }
        if (StringUtil.isNotEmpty(planPageQueryRequest.getOuterId())) {
            // 根据外部货品编码转内部编码
            List<ScItemSDO> scItemList = salesPlanOutCommonService.getScItemListByOutId(planPageQueryRequest.getOuterId().trim());
            if (CollectionUtils.isNotEmpty(scItemList)) {
                List<String> scItemIdList = scItemList.stream().map(ScItemSDO::getScItemId).filter(StringUtils::isNotEmpty).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(scItemIdList)) {
                    planPageQueryRequest.setScItemIdList(scItemIdList);
                }
            } else {
                planPageQueryRequest.setScItemId("XXXXX");
            }
        }
    }

    private List<OrganizationSDO> organizationSDOList(OrganizationSelectRequest organizationSelectRequest) {
        List<OrganizationSDO> organizationSDOList = new ArrayList<>();
        if (OrganizationTypeEnum.COMPANY.getCode() < Integer.valueOf(organizationSelectRequest.getRelatedOrganizationType())) {
            //登录人的角色小于分子公司的,需要层级往上找
            GetTopOrganizationListRequest getTopOrganizationListRequest = GetTopOrganizationListRequest.builder()
                    .id(organizationSelectRequest.getRelatedOrganizationId())
                    .type(OrganizationTypeEnum.COMPANY.getCode()).build();
            Result<List<TopOrganizationListResponse>> topOrganizationList = otsPlatformEnhanceService.getTopOrganizationList(getTopOrganizationListRequest);
            topOrganizationList.getResult().forEach(topOrganizationListResponse -> {
                if (OrganizationTypeEnum.COMPANY.getCode().equals(topOrganizationListResponse.getType())) {
                    OrganizationSDO organizationSDO = new OrganizationSDO();
                    BeanUtils.copyProperties(topOrganizationListResponse, organizationSDO);
                    organizationSDOList.add(organizationSDO);
                }
            });
        } else if (OrganizationTypeEnum.COMPANY.getCode() == Integer.valueOf(organizationSelectRequest.getRelatedOrganizationType())) {
            //登录人为分子公司那一层，直接根据id查询名称
            BaselineGetOrganizationByIdsRequest baselineGetOrganizationByIdsRequest = BaselineGetOrganizationByIdsRequest.builder()
                    .ids(Lists.newArrayList(organizationSelectRequest.getRelatedOrganizationId()))
                    .build();
            Object response = baseDataService.baselineGetOrganizationByIds(baselineGetOrganizationByIdsRequest);
            buildResponse(response, organizationSDOList);
        } else if (OrganizationTypeEnum.COMPANY.getCode() > Integer.valueOf(organizationSelectRequest.getRelatedOrganizationType())) {
            //登录人大于分子分子公司级别，查询查询所有的业务单元
//            BaselineGetOrganizationByTypeRequest baselineGetOrganizationByTypeRequest = BaselineGetOrganizationByTypeRequest.builder()
//                    .type(OrganizationTypeEnum.COMPANY.getCode().toString())
//                    .build();
//            Object response = baseDataService.baselineGetOrganizationByType(baselineGetOrganizationByTypeRequest);
//            buildResponse(response, organizationSDOList);
            GetOrganizationByTypeResponse response = organizationQueryService.getOrganizationByType(GetOrganizationByTypeRequest.builder().type(OrganizationTypeEnum.COMPANY.getCode().toString()).build());
            if (null != response.getResult() && null != response.getResult() && org.apache.commons.collections4.CollectionUtils.isNotEmpty(response.getResult())) {
                response.getResult().forEach(x -> {
                    if (OrganizationTypeEnum.COMPANY.getCode().equals(x.getType())) {
                        OrganizationSDO organizationSDO = new OrganizationSDO();
                        BeanUtils.copyProperties(x, organizationSDO);
                        organizationSDOList.add(organizationSDO);
                    }
                });
            }
        }
        return organizationSDOList;
    }

    private void buildResponse(Object response, List<OrganizationSDO> organizationSDOList) {
        Map saleMap = (Map) response;
        JSONArray result = com.alibaba.fastjson.JSONObject.parseObject(com.alibaba.fastjson.JSONObject.toJSONString(saleMap)).getJSONArray("result");
        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(result)) {
            for (int i = 0; i < result.size(); i++) {
                OrganizationSDO sdo = new OrganizationSDO();
                com.alibaba.fastjson.JSONObject organizationSDO = result.getJSONObject(i).getJSONObject("organizationSDO");
                String id = Optional.ofNullable(organizationSDO.getString("id")).orElse(null);
                String name = Optional.ofNullable(organizationSDO.getString("name")).orElse(null);
                sdo.setId(id);
                sdo.setName(name);
                organizationSDOList.add(sdo);
            }
        }
    }

    private void listPageResultConverter(PageResult<List<SalesPlanScItemSDO>> listPageResult) {
        if (null == listPageResult || CollectionUtils.isEmpty(listPageResult.getContent())) {
            return;
        }

        List<SalesPlanScItemSDO> salesPlanScItemSDOS = listPageResult.getContent();
        Map<String, EmployeeSDO> employeeSDOMap = Maps.newHashMap();
        Map<String, OrganizationSDO> organizationSDOMap = Maps.newHashMap();
        // 获取货品外部编码
        Set<String> scItemSet = salesPlanScItemSDOS.stream().map(SalesPlanScItemSDO::getScItemId).collect(Collectors.toSet());
        Map<String, ScItemSDO> scItemMapByOutMap = salesPlanOutCommonService.getScItemMapByIds(scItemSet, false);
        // 获取创建人名称
        List<String> ids = salesPlanScItemSDOS.stream().map(o -> o.getCreator().replace("CZ_", "")).distinct()
                .collect(Collectors.toList());
        ids.addAll(salesPlanScItemSDOS.stream().map(o -> o.getUpdater().replace("CZ_", "")).distinct()
                .collect(Collectors.toList()));
        List<EmployeeSDO> employeeList = platformEnhanceRepository.getEmployeeList(ids);
        if (CollectionUtils.isNotEmpty(employeeList)) {
            employeeSDOMap = employeeList.stream().collect(Collectors.toMap(EmployeeSDO::getId, a -> a, (a, b) -> a));
        }

        Set<String> salesUnitCodes = salesPlanScItemSDOS.stream().map(SalesPlanScItemSDO::getOrgBusinessUnitCode).collect(Collectors.toSet());
        Set<String> salesOrgCodes = salesPlanScItemSDOS.stream().map(SalesPlanScItemSDO::getOrgSalesOrganizationCode).collect(Collectors.toSet());
        Set<String> salesChannelCodes = salesPlanScItemSDOS.stream().map(SalesPlanScItemSDO::getOrgSalesChannelCode).collect(Collectors.toSet());
        List<String> codeList = Lists.newArrayList(salesUnitCodes);
        codeList.addAll(salesOrgCodes);
        codeList.addAll(salesChannelCodes);
        BaselineGetOrganizationByIds2Request request = new BaselineGetOrganizationByIds2Request();
        request.setIds(codeList);
        BaselineGetOrganizationByIds2Response result = baseDataService.baselineGetOrganizationByIds2(request);
        if (null != result && CollectionUtils.isNotEmpty(result.getResult())) {
            organizationSDOMap = result.getResult().stream().collect(Collectors.toMap(OrganizationSDO::getId, a -> a, (a , b) -> a));
        }

        for (SalesPlanScItemSDO salesPlanScItemSDO : salesPlanScItemSDOS) {
            EmployeeSDO creatorEmployeeSDO = employeeSDOMap.get(salesPlanScItemSDO.getCreator().replace("CZ_", ""));
            if (Objects.nonNull(creatorEmployeeSDO)) {
                //创建人
                salesPlanScItemSDO.setCreatorName(creatorEmployeeSDO.getName());
            }
            EmployeeSDO updaterEmployeeSDO = employeeSDOMap.get(salesPlanScItemSDO.getUpdater().replace("CZ_", ""));
            if (Objects.nonNull(updaterEmployeeSDO)) {
                //修改人
                salesPlanScItemSDO.setUpdaterName(updaterEmployeeSDO.getName());
            }
            if (!Objects.isNull(scItemMapByOutMap) && !scItemMapByOutMap.isEmpty()) {
                ScItemSDO scItemSDO = scItemMapByOutMap.get(salesPlanScItemSDO.getScItemId());
                if (Objects.nonNull(scItemSDO)) {
                    //外部编码
                    salesPlanScItemSDO.setOuterId(scItemSDO.getOuterId());
                    salesPlanScItemSDO.setScItemName(scItemSDO.getTitle());
                }
            }
            // 获取业务单元、销售组织、销售渠道名称
            OrganizationSDO business = organizationSDOMap.get(salesPlanScItemSDO.getOrgBusinessUnitCode());
            if (Objects.nonNull(business)) {
                salesPlanScItemSDO.setOrgBusinessUnitName(business.getName());
                salesPlanScItemSDO.setOutOrgBusinessUnitCode(business.getCode());
            }
            OrganizationSDO saleOrg = organizationSDOMap.get(salesPlanScItemSDO.getOrgSalesOrganizationCode());
            if (Objects.nonNull(saleOrg)) {
                salesPlanScItemSDO.setOrgSalesOrganizationName(saleOrg.getName());
                salesPlanScItemSDO.setOutOrgSalesOrganizationCode(saleOrg.getCode());
            }
            OrganizationSDO channel = organizationSDOMap.get(salesPlanScItemSDO.getOrgSalesChannelCode());
            if (Objects.nonNull(channel)) {
                salesPlanScItemSDO.setOrgSalesChannelName(channel.getName());
                salesPlanScItemSDO.setOutOrgSalesChannelCode(channel.getCode());
            }
            if (Objects.nonNull(salesPlanScItemSDO.getCostInsuranceFreight())) {
                DecimalFormat df = new DecimalFormat("######0.00");
                double doubleValue = salesPlanScItemSDO.getCostInsuranceFreight().doubleValue() / 100.00;
                salesPlanScItemSDO.setCostInsuranceFreightName(String.valueOf(df.format(doubleValue)));
            }
            if (Objects.nonNull(salesPlanScItemSDO.getOutboundPrice())) {
                DecimalFormat df = new DecimalFormat("######0.00");
                double doubleValue = salesPlanScItemSDO.getOutboundPrice().doubleValue() / 100.00;
                salesPlanScItemSDO.setOutboundPriceName(String.valueOf(df.format(doubleValue)));
            }
        }
    }

    @FacadeInvoker
    @Override
    public Result<SalesPlanScItemSDO> queryProductPlanInfoById(SalesPlanScItemQueryRequest
                                                                       salesPlanScItemQueryRequest) {
        SalesPlanScItemSDO salesPlanScItemSdo = salesPlanScItemRepository.querySalesPlanScItem(salesPlanScItemQueryRequest);
        return Result.success(salesPlanScItemSdo);
    }

    @Override
    @FacadeInvoker
    public Result<List<SalesPlanScItemSDO>> batchQuerySalesPlanScItem(BatchQuerySalesPlanScItemRequest
                                                                              batchQuerySalesPlanScItemRequest) {
        List<SalesPlanScItemSDO> salesPlanScItemSDOS = salesPlanScItemRepository.batchQuerySalesPlanScItem(batchQuerySalesPlanScItemRequest);
        return Result.success(salesPlanScItemSDOS);
    }
}
